import service from '../utils/http';
import { ApiBase } from '../types/api/apiBase';
import { Miner, MinerApiResult } from '../types/miner';
import { fetchGroup } from './group';
import { Group } from '../types/group';
import { fetchMonitorInfo } from './monitor';
import currencyListModel from '@/models/currencylist';
import formatHash from '@/utils/format/formatHash';
import { Currency } from '@/types/currency';
import { FetchMinerParams } from '@/hooks/swr/useFetchMinerSwr';

export function fetchOriginMiner(params: FetchMinerParams) {
  return new Promise<MinerApiResult>(async (resolve, reject) => {
    const res = await service.get<ApiBase<MinerApiResult>>('/web/miner', {
      params,
    });
    if (res.data.code === 0) {
      if (res.data.result.list === null) {
        res.data.result.list = [];
      }
      resolve(res.data.result);
    } else {
      reject();
    }
  });
}

export function getCardStatus(
  hash: number,
  temp: number,
  checkGpuHashWarning: boolean | undefined,
  gpuErrorHash: number,
  gpuWaringHash: number,
  t1: number,
  t2: number,
) {
  if (hash <= 0) {
    return 'abnormal-count';
  }
  if (temp !== null) {
    if (temp <= 0 || temp > t2) {
      return 'abnormal-count';
    }
  }
  if (checkGpuHashWarning && hash <= gpuErrorHash) {
    return 'abnormal-count';
  }

  if (temp > t1 && temp <= t2) {
    return 'warning-count';
  }
  if (checkGpuHashWarning && hash < gpuWaringHash) {
    return 'warning-count';
  }

  return '';
}

function getHashStatus(
  hash: number,
  checkGpuHashWarning: boolean | undefined,
  gpuErrorHash: number,
  gpuWaringHash: number,
) {
  if (hash <= 0) {
    return 'abnormal-count';
  }

  if (checkGpuHashWarning && hash <= gpuErrorHash) {
    return 'abnormal-count';
  }

  if (checkGpuHashWarning && hash < gpuWaringHash) {
    return 'warning-count';
  }

  return '';
}

function getCards(
  temperatureArr: string[],
  hashAllArr: string[],
  t1: number,
  t2: number,
  checkGpuHashWarning: boolean | undefined = true,
  gpuWaringHash: number,
  gpuErrorHash: number,
  coin: string,
  currency: Currency | undefined,
) {
  return temperatureArr.map((_temp, index) => {
    const hash = Number(hashAllArr[index]);
    const temp = Number(_temp);
    const status = getCardStatus(
      hash,
      temp,
      checkGpuHashWarning,
      gpuErrorHash,
      gpuWaringHash,
      t1,
      t2,
    );
    const hashFormat = formatHash(hash, coin, currency, false);
    const tempStatus = getCardStatus(
      hash,
      temp,
      false,
      gpuErrorHash,
      gpuWaringHash,
      t1,
      t2,
    );

    const hashStatus = getHashStatus(
      hash,
      checkGpuHashWarning,
      gpuErrorHash,
      gpuWaringHash,
    );
    return {
      temp,
      hash,
      hashFormat,
      status,
      tempStatus,
      hashStatus,
    };
  });
}

export interface MinerPageModel {
  minerList: Miner[];
  total: number;
}

export function fetchMiner(
  params: FetchMinerParams,
  t1: number,
  t2: number,
  groupListMap?: Record<string, Group>,
) {
  return new Promise<MinerPageModel>(async (resolve, reject) => {
    try {
      let originMiner = await fetchOriginMiner(params);
      const currencyMap = await currencyListModel.getCurrencyMap();

      const minerList = originMiner.list.map((miner) => {
        const group = groupListMap
          ? groupListMap[miner.gid.toString()]
          : {
              checkGpuHashWarning: false,
              gpuWaringHash: 10,
              gpuErrorHash: 0,
            };
        const currency = currencyMap.get(miner.coin);
        if (miner.card === 0) {
          return {
            ...miner,
            group,
            cards: [],
            hashFormat: formatHash(miner.hash, miner.coin, currency),
            scHashFormat: formatHash(miner.sc_hash, miner.sc_coin, currency),
          };
        }
        const temperatureArr = miner.temperature.split('|');
        const hashAllArr = miner.hash_all.split('|');
        const coin = miner.coin;

        const checkGpuHashWarning = group
          ? group.checkGpuHashWarning
            ? group.checkGpuHashWarning
            : false
          : true;
        return {
          ...miner,
          group,
          hashFormat: formatHash(miner.hash, coin, currency),
          scHashFormat: formatHash(miner.sc_hash, miner.sc_coin, currency),
          cards: getCards(
            temperatureArr,
            hashAllArr,
            t1,
            t2,
            checkGpuHashWarning,
            group.gpuWaringHash || 10,
            group.gpuErrorHash || 0,
            coin,
            currency,
          ),
        };
      });
      resolve({
        total: originMiner.total,
        minerList,
      });
    } catch (e) {
      reject(e);
    }
  });
}
